/*
 * 功能：全局异常处理器，用于统一处理系统中抛出的各种异常，并返回统一的错误信息。
 * 作者：张杨(Sunny)
 * 日期：2025/1/6 下午8:53
 */
package com.example.springboot.exception;

// 导入必要的类和接口

import com.example.springboot.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.IOException;
import java.util.concurrent.TimeoutException;


@ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理 ServiceException 类型的异常
    @ExceptionHandler(ServiceException.class) // 指定处理的异常类型为ServiceException
    @ResponseBody // 将返回值转换为JSON格式
    public Result serviceException(ServiceException e) {
        return Result.error(e.getCode(), e.getMessage()); // 返回错误信息
    }

    // 创建一个日志记录器实例，用于记录异常信息
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    // 处理数据库唯一键冲突异常
    @ExceptionHandler(DuplicateKeyException.class)
    public Result handleDuplicateKeyException(DuplicateKeyException e) {
        logger.error("数据库唯一键冲突异常：", e);
        return Result.error("插入数据库错误");
    }

    // 处理数据库访问异常
    @ExceptionHandler(DataAccessException.class)
    public Result handleDataAccessException(DataAccessException e) {
        logger.error("数据库访问异常：", e);
        return Result.error("数据库访问错误");
    }

    // 处理文件上传大小超过限制的异常
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public Result handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        logger.error("文件上传大小超过限制异常：", e);
        return Result.error("文件上传大小超过限制");
    }

    // 处理请求的资源不存在的异常
    @ExceptionHandler(NoHandlerFoundException.class)
    public Result handleNoHandlerFoundException(NoHandlerFoundException e) {
        logger.error("请求的资源不存在异常：", e);
        return Result.error("请求的资源不存在");
    }

    // 处理IO操作异常
    @ExceptionHandler(IOException.class)
    public Result handleIOException(IOException e) {
        logger.error("IO操作异常：", e);
        return Result.error("IO操作错误");
    }

    // 处理非法参数异常
    @ExceptionHandler(IllegalArgumentException.class)
    public Result handleIllegalArgumentException(IllegalArgumentException e) {
        logger.error("非法参数异常：", e);
        return Result.error("非法参数错误");
    }

    // 处理非法状态异常
    @ExceptionHandler(IllegalStateException.class)
    public Result handleIllegalStateException(IllegalStateException e) {
        logger.error("非法状态异常：", e);
        return Result.error("非法状态错误");
    }

    // 处理操作超时异常
    @ExceptionHandler(TimeoutException.class)
    public Result handleTimeoutException(TimeoutException e) {
        logger.error("操作超时异常：", e);
        return Result.error("操作超时");
    }

    // 处理请求体格式错误异常
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("请求体格式错误异常：", e);
        return Result.error("请求体格式错误");
    }

    // 处理参数验证失败异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        logger.error("参数验证失败异常：", e);
        return Result.error("参数验证失败");
    }

    // 处理所有其他未捕获的异常
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        logger.error("系统异常：", e);
        return Result.error("系统错误");
    }
}
